package _0_4_买卖股票

/**
原题链接:
https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-ii/

122. 买卖股票的最佳时机 II  (在持有一支股票的前提下, 可以进行多次买卖)
给你一个整数数组 prices ，其中 prices[i] 表示某支股票第 i 天的价格。
在每一天，你可以决定是否购买和/或出售股票。
你在任何时候 最多 只能持有 一股 股票。你也可以先购买，然后在 同一天 出售。
返回 你能获得的 最大 利润 。

示例 1：
输入：prices = [7,1,5,3,6,4]
输出：7
解释：在第 2 天（股票价格 = 1）的时候买入，在第 3 天（股票价格 = 5）的时候卖出, 这笔交易所能获得利润 = 5 - 1 = 4 。
     随后，在第 4 天（股票价格 = 3）的时候买入，在第 5 天（股票价格 = 6）的时候卖出, 这笔交易所能获得利润 = 6 - 3 = 3 。
     总利润为 4 + 3 = 7 。

示例 2：
输入：prices = [1,2,3,4,5]
输出：4
解释：在第 1 天（股票价格 = 1）的时候买入，在第 5 天 （股票价格 = 5）的时候卖出, 这笔交易所能获得利润 = 5 - 1 = 4 。
     总利润为 4 。

示例 3：
输入：prices = [7,6,4,3,1]
输出：0
解释：在这种情况下, 交易无法获得正利润，所以不参与交易可以获得最大利润，最大利润为 0 。

思路：
一. dp数组含义
	dp[i][0] 表示第i天持有股票所得现金
	dp[i][1] 表示第i天不持有股票所得现金

如果第i天持有股票即dp[i][0], 那么可以由两个状态推出来
	*第i-1就持有股票，那么就保持现状，所得现金就是昨天持有股票所得现金 即: dp[i-1][0]
	*第i天买入股票, 所得现金就是昨天不持有股票的所得现金减去今天的股票价格 即: dp[i-1][1] - prices[i]

本题由于一只股票可以买卖多次, 所以当第i天买入股票的时候，所持有的现金可能有之前买卖过的利润
那么第i天持有股票即dp[i][0], 如果是第i天买入股票,所得现金就是昨天不持有股票的所得现金减去今天的股票价格 即: dp[i-1][1] - prices[i]

本题由于一只股票可以买卖多次，所以当第i天买入股票的时候，所持有的现金可能有之前买卖过的利润。
那么第i天持有股票即dp[i][0], 如果是第i天买入股票，所得现金就是昨天不持有股票的所得现金减去今天的股票价

再来看看如果第i天不持有股票即dp[i][1]的情况, 依然可以由两个状态推出来
* 第i-1天就不持有股票,那么就保持现状, 所得现金就是昨天不持有股票的所得现金 即: dp[i-1][1]
* 第i天卖出股票, 所得现金就是按照今天股票价格卖出后所得现金 即: prices[i] + dp[i-1][0]


*/

// 买卖股票的最佳时机Ⅱ 动态规划
// 时间复杂度：O(n) 空间复杂度：O(n)
func maxProfit122(prices []int) int {

	n := len(prices)

	dp := make([][]int, len(prices)) //声明dp数组
	for i := range dp {
		dp[i] = make([]int, 2)
	}

	dp[0][0] = -prices[0] //第0天持有股票状态的值, 那就是直接买prices[0]的股票呗
	dp[0][1] = 0

	//填充dp数组
	for i := 1; i < n; i++ {
		//第i天持有股票的状态, 可能是i-1天就持有了: dp[i-1][0], 也可能是第i天才买入的,那么需在i-1天不持有股票的基础上,购买第i天的股票: dp[i-1][1]-prices[i]
		dp[i][0] = max(dp[i-1][0], dp[i-1][1]-prices[i])
		//第i天不持有股票的状态, 可能是i-1天就不持有了: dp[i-1][1], 也可能是第i天才卖出的, 那么需在i-1天持有股票的基础上,卖出第i天的股票: dp[i-1][0] + prices[i]
		dp[i][1] = max(dp[i-1][1], dp[i-1][0]+prices[i])
	}

	//返回prices[i]位置持有的现金数
	return dp[n-1][1]
}
